package com.wgo.bpot.server.persist.hibernate;

import java.io.Serializable;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.MappingException;
import org.hibernate.criterion.Restrictions;

import com.wgo.bpot.common.transport.exception.db.DatabaseException;
import com.wgo.bpot.server.persist.BasicPersistService;


public class HibernatePersistService extends BasicPersistService {
	
	private static final transient Logger log = Logger.getLogger(HibernatePersistService.class);

	public void createSchema() {
		HibernateUtil.createSchema(getRootConceptClass());
	}

	public void save(Object instanceToBeSaved) {
		HibernateUtil.getSessionFactory().getCurrentSession().save(instanceToBeSaved);
	}


	public void saveOrUpdate(Object instanceToBeSaved) {
		HibernateUtil.getSessionFactory().getCurrentSession().saveOrUpdate(instanceToBeSaved);
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getInstance(Class<T> type, Serializable id) {
		T result = null;
		try {
			result = (T)HibernateUtil.getSessionFactory().getCurrentSession().get(type,id);
		} catch (MappingException e) {
			String debugMessage = "Unable to retrieve systems before schemas have been created!" ;
			log.error(debugMessage, e);
			throw new DatabaseException(debugMessage, e);
		}
		return result;
	}

	public void startTransaction() {
		HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
	}

	public Object find(Class type, String fieldName, String fieldValue) {
        Criteria crit = HibernateUtil.getSessionFactory().getCurrentSession().createCriteria(type);
        crit.add(Restrictions.ilike(fieldName,fieldValue));
		return crit.uniqueResult();
	}

	public void close() {
		log.warn("Should not be used with Hibernate 3.0.1 and later.");
	}


	public boolean isTransactionActive() { //TODO: rename to isTransactionActive
		return HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().isActive();
	}


	/**
	 * Commit any pending transactions for this session.
	 */
	public void commitTransaction() {
		HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
	}


	public void rollbackTransaction() {
		HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
	}

}
